package com.zbj.homemade.spring.scan;

import com.zbj.homemade.spring.annotation.Configuration;
import com.zbj.homemade.spring.annotation.Import;
import com.zbj.homemade.spring.annotation.aop.EnableAspectJAutoProxy;
import com.zbj.homemade.spring.beans.BeanDefinitionRegistry;
import com.zbj.homemade.spring.beans.ConfigurationBeanDefinition;
import com.zbj.homemade.spring.beans.SimpleBeanDefinition;
import com.zbj.homemade.spring.exception.BeanRegistryException;
import com.zbj.homemade.spring.exception.ContextException;
import com.zbj.homemade.spring.factorylifecycle.BeanDefinitionRegistryPostProcessor;
import com.zbj.homemade.spring.utils.AnnoUtils;
import com.zbj.homemade.spring.utils.NameUtil;

/**
 * |                    .  ’   *   ‘  .
 * |               _6                    "     o0000o
 * |  o00o _    .%                         %. o0000000o
 * | o000000o.:                              :(0000000o
 * | o00000os                                  .000000o
 * |  o0000/     <b>不了不了,改需求真的伤身体</>   .000o
 * |    o0o                                       .0o
 * |     y        <b>我认为源代码,就是SkrSkr</>     .
 * |    y                                           ,
 * |   y          <b>小熊猫保佑,代码永不修改</>        ,
 * |   p                            .                 .
 * |   p                           @@.                .
 * |    y                        ;@@@;               .
 * |    \                       ;@@@@;.@.          ,;S
 * |     、                     .@@@@@@;       ,@@@@@
 * |     @\.            .****...*@@@@;     .@@@@@@@@@@@.
 * |    @@@@\.     . @@@@@@@@@@@@@@@;    .@@@@@@@@@@@@@@@.
 * |   @@@@@@@@@.@@@@@@@@@@@@@@@@;   .@@@@@@@@@@@@@@@@@@@@@.
 * |  @@@@@@..@@@@..@@@@@@..@@@@@ .@@...@@@@@..@@..@@@@@..@@.
 * | @@@@@@@@..@..@@@@@@@@@@@@@;.@@@..@..@@@..@@....@@@..@@@@.
 * |@y@@@@@@@@..@@@@@@@@..@@@@i@@@@..@@@..@..@@..@@..@..@@@@n@.
 * |@n@@@@@@@..@@@@@@@@..@@@@@@@@@..@@@@@...@@..@@@@...@@@@@n@@.
 * |@@@@@@@@..@@@@@@@@..@@@@@@@@@..@@@@@@@.@@..@@@@@..@@@@@@@@@@.
 * |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.
 *
 * @program: principle
 * @description:
 * @author: Yinn
 * @create: 2019-03-01 16:42
 **/
public class AnnotatedBeanDefinitionReader {

    /**
     * bean定义注册器
     */
    private BeanDefinitionRegistry registry;

    /**
     * 配置类
     */
    private Class<?>[] configClass;

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this.registry = registry;
    }

    public void register(Class<?>... classes) {

        if (classes == null)
            throw new BeanRegistryException("配置类为空！");

        for (Class<?> clazz : classes) {
            registerConfig(clazz, registry);
        }

    }

    /**
     * 注册配置类
     */
    private void registerConfig(Class<?> cls, BeanDefinitionRegistry registry) {

        if (!AnnoUtils.isClazzAnnotated(cls, Configuration.class))
            throw new ContextException(cls.getName() + " is not configuration class");

        ConfigurationBeanDefinition cbd = new ConfigurationBeanDefinition(cls);

        registry.registerBeanDefinition(NameUtil.toLowerCaseFirstOne(cls.getSimpleName()), cbd);


        if (AnnoUtils.isClazzAnnotated(cls,EnableAspectJAutoProxy.class)){
            EnableAspectJAutoProxy enableAspectJAutoProxy = cls.getAnnotation(EnableAspectJAutoProxy.class);
            Class<?> annoCls = enableAspectJAutoProxy.annotationType();
            if (AnnoUtils.isClazzAnnotated(annoCls,Import.class)){
                Import anImport = annoCls.getAnnotation(Import.class);
                Class<?>[] importClasses = anImport.value();

                if (importClasses != null && importClasses.length > 0){
                    for (Class<?> importClass : importClasses){
                        if (BeanDefinitionRegistryPostProcessor.class.isAssignableFrom(importClass)){
                            registry.registerBeanDefinition(NameUtil.getLikeBeanName(importClass), new SimpleBeanDefinition(importClass));

                        }
                    }
                }
            }
        }

    }

}
